package tt.dz.egobus.servicemanager.controller.car;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import tt.dz.egobus.servicemanager.base.controller.EntityController;
import tt.dz.egobus.servicemanager.base.service.ExtendBaseService;
import tt.dz.egobus.servicemanager.core.exception.BusinessException;
import tt.dz.egobus.servicemanager.entities.Bus;
import tt.dz.egobus.servicemanager.service.BusService;
import tt.dz.egobus.servicemanager.service.BusinessExceptionAlertService;
import tt.dz.egobus.servicemanager.service.DriverRegisterBusRelativeService;
import tt.dz.egobus.servicemanager.vo.BusViewVo;

import java.util.HashMap;
import java.util.Map;

import static tt.dz.egobus.servicemanager.bean.ServiceManagerCodeStatus.*;

/**
 * @author Anson
 * @date 17-3-16
 * @name
 * @since 1.0.1
 */
@RestController
@RequestMapping("/bus")
public class BusController extends EntityController<Bus, BusViewVo, String> {

    private static final Logger LOGGER = LoggerFactory.getLogger(BusController.class);

    @Autowired
    @Qualifier("busServiceImpl")
    private BusService service;


    @Autowired
    @Qualifier("businessExceptionAlertServiceImpl")
    private BusinessExceptionAlertService exceptionAlertService;

    @Autowired
    @Qualifier("driverRegisterBusRelativeServiceImpl")
    private DriverRegisterBusRelativeService driverRegisterBusRelativeService;


    @Override
    protected ExtendBaseService<Bus, String> getSelfService() {
        return this.service;
    }

    @Override
    protected BusViewVo newViewVo() {
        return new BusViewVo();
    }

    /**
     * @param busNo     判断某个车牌是否被占用
     * @param excludeId 【非必须】排除某个id
     * @author Anson
     * @date 17-4-20
     * @name 判断某个车牌号是否已经被占用
     * @since 1.0.4
     */
    public void validateBusNoExist(String busNo,
                                   String excludeId) throws BusinessException {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("eq#carNo", busNo);
        if (!StringUtils.isEmpty(excludeId)) {
            params.put("ne#id", excludeId);
        }
        int count = this.service.count(params);
        if (count > 0) {
            throw new BusinessException(BUS_NO_EXIST_ERROR.getCodeStatus());
        }
    }

    @Override
    protected void preInsertHandler(Bus bus) throws BusinessException {
        if (!StringUtils.isEmpty(bus.getCarNo())) {
            this.validateBusNoExist(bus.getCarNo(), null);
        }
    }

    /**
     * @param bus 当前车辆信息
     * @author Anson
     * @date 17-5-15
     * @name 在更新的时候, 是否存在车辆车牌被占用
     * 是否存在未处理完全的车辆异常处理
     * @since 1.0.4
     */
    @Override
    protected void preUpdateHandler(Bus bus) throws BusinessException {
        if (!StringUtils.isBlank(bus.getCarNo())) {
            this.validateBusNoExist(bus.getCarNo(), bus.getId());
            this.validateAlertException(bus);
        }
        if (!StringUtils.isBlank(bus.getId())) {
            //判断是否存在有效的司机之间绑定关系
            this.driverRegisterBusRelativeService.validateDriverelative(bus.getId(), true);
        }
        //判断当前是否存在司机控制的状态
        boolean isAliveDriverStatusController = this.service.isBusStatusInDriverController(bus);
        if(isAliveDriverStatusController){
            throw new BusinessException(BUS_STATUS_IN_DRIVER_CONTROLLER.getCodeStatus());
        }
    }


    /**
     * @param id 当前车辆的id
     * @author Anson
     * @date 17-4-6
     * @name 删除某一个车辆的时候，判断当前注册服务是否存在
     * @since 1.0.4
     */
    @Override
    protected void preDeleteHandler(String id) throws BusinessException {
        this.service.preDeleteBusService(id);
    }

    /**
     * @param id 生成车辆id二维码
     * @author Anson
     * @date 17-3-14
     * @name 车辆二维码生成
     * @since 1.0.1
     */
    @RequestMapping("/generationQRCode")
    public ResponseEntity<byte[]> generationQRCode(@RequestParam("id") String id) {
        //设置请求头内容,告诉浏览器代开下载窗口
        HttpHeaders headers = new HttpHeaders();
        Bus bus = this.service.get(id);
        byte[] bytes = null;
        if (bus == null) {
            //未找到车辆关系
        } else {
            try {
                byte[] bs = bus.getCarNo().getBytes("utf-8");
                String fileName = new String(bs, "ISO-8859-1") + ".png";
                headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
                headers.setContentDispositionFormData("attachment", fileName);
                bytes = this.service.generationQRCode(id);
            } catch (BusinessException e) {
                LOGGER.error("车辆二维码生成", e);
            } catch (Exception e) {
                LOGGER.error("车辆二维码生成", e);
            }
        }

        return new ResponseEntity<byte[]>(bytes,
                headers, HttpStatus.CREATED);
    }


    /**
     * @param bus 当前车辆信息
     * @author Anson
     * @date 17-5-15
     * @name 当前车辆是否存在异常未处理
     * @since 1.0.4
     */
    private void validateAlertException(Bus bus) {
        String busNo = null;
        int busStatus = Integer.MAX_VALUE;
        if (bus != null && !StringUtils.isBlank(busNo = bus.getCarNo())) {
            //若当前状态不在校验异常排除的状态外的时候,需要校验是否存在异常状态
            busStatus = bus.getStatus();
            if (!ArrayUtils.contains(Bus.getAbleUpdateExcludeBusCodeAlertExcept(), busStatus)) {
                boolean isExist = exceptionAlertService.isExistValidateBusUnDeal(busNo);
                if (isExist) {
                    throw new BusinessException(BUS_EXIST_ALERT_EXCEPTION_UNDONE.getCodeStatus());
                }
            }
        }
    }

}